package gold.digger;

import gold.utils.InputUtil;

import java.util.*;
import java.util.stream.Collectors;

/**
 * Created by fanzhenyu02 on 2021/12/10.
 * common problem solver template.
 */
public class LC910 {
    public long startExecuteTime = System.currentTimeMillis();


    /*
     * @param 此题目参考了别人代码
     * 这是因为问题情况较为复杂
     * 未来需要再次复习此道题目
     * @return:
     */
    class Solution {
        public int smallestRangeII(int[] nums, int k) {
            TreeSet<Integer> set = new TreeSet<>();
            for (int num : nums) {
                set.add(num);
            }

            final List<Integer> collectList = set.stream().collect(Collectors.toList());
            int len = collectList.size(), res = collectList.get(len - 1) - collectList.get(0);
            for (int i = 0; i < len - 1; i++) {
                int high = Math.max(collectList.get(i) + k, collectList.get(len - 1) - k);
                int low = Math.min(collectList.get(i + 1) - k, collectList.get(0) + k);
                res = Math.min(res, high - low);
            }

            return res;
        }
    }

    public void run() {
        Solution solution = new Solution();

//        输入：nums = [1], k = 0
//        输出：0
//        解释：分数 = max(nums) - min(nums) = 1 - 1 = 0 。
        System.out.println(solution.smallestRangeII(InputUtil.toIntegerArray("[1]"), 0));
//
//        输入：nums = [0,10], k = 2
//        输出：6
//        解释：将数组变为 [2, 8] 。分数 = max(nums) - min(nums) = 8 - 2 = 6 。
        System.out.println(solution.smallestRangeII(InputUtil.toIntegerArray("[0,10]"), 2));

        //输入：nums = [1,3,6], k = 3
//        输出：3
//        解释：将数组变为 [4, 6, 3] 。分数 = max(nums) - min(nums) = 6 - 3 = 3 。
        System.out.println(solution.smallestRangeII(InputUtil.toIntegerArray("[1,3,6]"), 3));

        System.out.println(solution.smallestRangeII(InputUtil.toIntegerArray("[1,3,10]"), 4));
    }

    public static void main(String[] args) throws Exception {
        LC910 an = new LC910();
        an.run();

        System.out.println("\ncurrent solution total execute time: " + (System.currentTimeMillis() - an.startExecuteTime) + " ms.");
    }
}
